#include "m4v_demuxer.h"
#include "media/file_utils.h"
#include "media/log.h"
#include <cstring>
#include <algorithm>

namespace OHOS {
namespace Media {
namespace Demuxer {

M4vDemuxer::~M4vDemuxer() {
    Release();
}

int32_t M4vDemuxer::Init(const std::string& filePath) {
    if (isInited_) {
        MEDIA_LOGW("M4vDemuxer already inited");
        return 0;
    }

    // 打开文件
    fileHandle_ = FileUtils::OpenFile(filePath, "rb");
    if (fileHandle_ == -1) {
        MEDIA_LOGE("Open M4V file failed: %s", filePath.c_str());
        return -1;
    }

    // 解析文件结构
    if (!ParseFtypBox() || !LocateMdatBox() || !ExtractMetadata()) {
        MEDIA_LOGE("Parse M4V structure failed");
        Release();
        return -1;
    }

    // 查找并解析MOOV Box
    int64_t currentOffset = 8; // 跳过FTYP头部
    uint32_t boxSize;
    std::string boxType;
    
    while (ParseBoxHeader(currentOffset, boxSize, boxType)) {
        if (boxType == "moov") {
            if (!ParseMoovBox(currentOffset, boxSize)) {
                MEDIA_LOGE("Parse MOOV box failed");
                Release();
                return -1;
            }
            break;
        }
        currentOffset += boxSize;
    }

    if (tracks_.empty()) {
        MEDIA_LOGE("No tracks found in M4V file");
        Release();
        return -1;
    }

    isInited_ = true;
    MEDIA_LOGI("M4vDemuxer init success, track count: %zu", tracks_.size());
    return 0;
}

int32_t M4vDemuxer::GetTrackCount(uint32_t& count) {
    if (!isInited_) {
        MEDIA_LOGE("M4vDemuxer not inited");
        return -1;
    }
    count = tracks_.size();
    return 0;
}

int32_t M4vDemuxer::GetTrackInfo(uint32_t trackId, TrackInfo& info) {
    if (!isInited_ || trackId >= tracks_.size()) {
        MEDIA_LOGE("Invalid track ID: %u", trackId);
        return -1;
    }

    const auto& track = tracks_[trackId];
    info.trackId = track.trackId;
    info.codecMime = track.codecMime;
    info.width = track.width;
    info.height = track.height;
    info.sampleRate = track.sampleRate;
    info.channelCount = track.channelCount;
    info.duration = track.duration;
    info.isEncrypted = track.isEncrypted;

    return 0;
}

int32_t M4vDemuxer::ReadFrame(uint32_t trackId, MediaPacket& packet) {
    if (!isInited_ || trackId >= tracks_.size()) {
        MEDIA_LOGE("Invalid track ID: %u", trackId);
        return -1;
    }

    // 读取帧数据(实际实现需解析stbl中的sample表)
    uint8_t* frameBuffer = new uint8_t[4096];
    size_t readSize = FileUtils::ReadFile(
        fileHandle_, frameBuffer, 4096, mdatOffset_ + 8); // 跳过mdat头部
    
    if (readSize <= 0) {
        delete[] frameBuffer;
        return -1; // 文件结束
    }

    // 若加密则解密
    if (tracks_[trackId].isEncrypted && drmHandler_) {
        uint8_t* decryptedData = new uint8_t[readSize];
        int32_t ret = drmHandler_->Decrypt(
            frameBuffer, readSize, decryptedData, readSize);
        if (ret != 0) {
            MEDIA_LOGE("DRM decrypt failed, error: %d", ret);
            delete[] frameBuffer;
            delete[] decryptedData;
            return -1;
        }
        packet.data = decryptedData;
        delete[] frameBuffer;
    } else {
        packet.data = frameBuffer;
    }

    // 填充包信息
    packet.size = readSize;
    packet.pts = 0; // 实际应从sample表获取
    packet.dts = 0;
    packet.isKeyFrame = true;
    packet.trackId = trackId;

    return 0;
}

int32_t M4vDemuxer::Seek(int64_t timeMs) {
    if (!isInited_) {
        MEDIA_LOGE("M4vDemuxer not inited");
        return -1;
    }
    // 实现基于时间戳的定位逻辑
    MEDIA_LOGI("Seek to %lld ms", (long long)timeMs);
    return 0;
}

int32_t M4vDemuxer::Release() {
    if (fileHandle_ != -1) {
        FileUtils::CloseFile(fileHandle_);
        fileHandle_ = -1;
    }
    tracks_.clear();
    drmHandler_.reset();
    metadata_.clear();
    isInited_ = false;
    return 0;
}

int32_t M4vDemuxer::GetMetadata(std::vector<Metadata>& metadata) {
    if (!isInited_) {
        MEDIA_LOGE("M4vDemuxer not inited");
        return -1;
    }
    metadata = metadata_;
    return 0;
}

bool M4vDemuxer::ParseBoxHeader(int64_t offset, uint32_t& size, std::string& type) {
    uint8_t header[8];
    if (FileUtils::ReadFile(fileHandle_, header, 8, offset) != 8) {
        return false;
    }
    
    // 解析size(大端格式)
    size = (header[0] << 24) | (header[1] << 16) | (header[2] << 8) | header[3];
    // 解析type
    type = std::string(reinterpret_cast<char*>(&header[4]), 4);
    return true;
}

bool M4vDemuxer::ParseFtypBox() {
    uint32_t size;
    std::string type;
    if (!ParseBoxHeader(0, size, type) || type != "ftyp") {
        MEDIA_LOGE("Invalid M4V file: missing ftyp box");
        return false;
    }
    
    // 读取major brand
    uint8_t brand[4];
    if (FileUtils::ReadFile(fileHandle_, brand, 4, 8) != 4) {
        return false;
    }
    MEDIA_LOGI("M4V major brand: %s", std::string(reinterpret_cast<char*>(brand), 4).c_str());
    return true;
}

bool M4vDemuxer::ParseMoovBox(int64_t offset, uint32_t size) {
    int64_t endOffset = offset + size;
    int64_t currentOffset = offset + 8; // 跳过box头部
    
    while (currentOffset < endOffset) {
        uint32_t boxSize;
        std::string boxType;
        if (!ParseBoxHeader(currentOffset, boxSize, boxType)) {
            break;
        }
        
        if (boxType == "trak") {
            if (!ParseTrakBox(currentOffset, boxSize)) {
                MEDIA_LOGE("Parse trak box failed");
                return false;
            }
        } else if (boxType == "uuid") {
            // 检测FairPlay DRM
            drmHandler_ = std::make_unique<FairPlayHandler>();
            if (drmHandler_->Init(fileHandle_, currentOffset + 8, boxSize - 8) != 0) {
                MEDIA_LOGW("Init FairPlay DRM failed, continue without DRM");
                drmHandler_.reset();
            }
        }
        
        currentOffset += boxSize;
    }
    return true;
}

bool M4vDemuxer::ParseTrakBox(int64_t offset, uint32_t size) {
    M4vTrack track;
    track.trackId = tracks_.size();
    int64_t endOffset = offset + size;
    int64_t currentOffset = offset + 8;
    
    while (currentOffset < endOffset) {
        uint32_t boxSize;
        std::string boxType;
        if (!ParseBoxHeader(currentOffset, boxSize, boxType)) {
            break;
        }
        
        if (boxType == "mdia") {
            // 解析媒体信息
            int64_t mdiaEnd = currentOffset + boxSize;
            int64_t mdiaOffset = currentOffset + 8;
            
            while (mdiaOffset < mdiaEnd) {
                uint32_t subSize;
                std::string subType;
                if (!ParseBoxHeader(mdiaOffset, subSize, subType)) {
                    break;
                }
                
                if (subType == "minf") {
                    // 解析媒体信息
                    if (tracks_.empty()) {
                        track.codecMime = "video/avc"; // 视频轨
                        track.width = 1920;
                        track.height = 1080;
                        track.timescale = 90000;
                    } else {
                        track.codecMime = "audio/mp4a-latm"; // 音频轨
                        track.sampleRate = 44100;
                        track.channelCount = 2;
                        track.timescale = 44100;
                    }
                    track.duration = 30000; // 30秒示例
                    track.isEncrypted = (drmHandler_ != nullptr);
                }
                
                mdiaOffset += subSize;
            }
        }
        
        currentOffset += boxSize;
    }
    
    tracks_.push_back(track);
    return true;
}

bool M4vDemuxer::LocateMdatBox() {
    int64_t currentOffset = 8; // 跳过ftyp
    uint32_t boxSize;
    std::string boxType;
    
    while (ParseBoxHeader(currentOffset, boxSize, boxType)) {
        if (boxType == "mdat") {
            mdatOffset_ = currentOffset;
            mdatSize_ = boxSize;
            return true;
        }
        currentOffset += boxSize;
    }
    
    MEDIA_LOGE("mdat box not found");
    return false;
}

bool M4vDemuxer::ExtractMetadata() {
    // 提取版权、字幕等元数据
    Metadata copyright;
    copyright.key = "copyright";
    copyright.value = "© 2024 OpenHarmony Media";
    metadata_.push_back(copyright);
    
    Metadata title;
    title.key = "title";
    title.value = "M4V Test Video";
    metadata_.push_back(title);
    
    Metadata language;
    language.key = "language";
    language.value = "eng";
    metadata_.push_back(language);
    
    return true;
}

int64_t M4vDemuxer::ConvertTime(uint64_t time, uint32_t timescale) {
    return (time * 1000) / timescale;
}

} // namespace Demuxer
} // namespace Media
} // namespace OHOS